// 文件名：search_results_cache.cpp
// 目的：实现一个简单的搜索结果缓存（SearchCache），支持：
//   - 添加结果页（docId, score）
//   - 依据分数阈值批量移除低分结果（erase-remove 惯用法）
//   - 分页获取结果的“拷贝视图”（返回子区间副本）
// 说明与注意：
//   - 数据结构：使用 std::vector<ResultPage> 顺序存储，追加写入高效、遍历缓存友好。
//   - removeLowScore：线性时间 O(n)；std::remove_if 将未删除元素前移，保持其相对顺序稳定。
//   - page：当前返回的是“副本”（拷贝）而非视图；若分页频繁或页面很大，拷贝成本显著，
//           可考虑返回迭代器区间、std::span（C++20）或共享指针/索引范围。
//   - 线程安全：本类非线程安全；如需并发访问，请在外部加锁或使用并发容器。
//   - 边界条件：page 假设 offset >= 0 且 limit >= 0；否则行为未定义（负数会导致迭代器越界）。
//   - 排序策略：当前未对分数排序；若需按分数降序分页，可在插入时维护有序性或调用 std::stable_sort。
//   - 精度注意：score 为 float，阈值比较使用严格小于（< threshold）；如需包含阈值，调整为 <=。

#include <vector>
#include <string>
#include <algorithm>
#include <iostream>

// 单条结果：文档 ID 与相关性分数
struct ResultPage {
    std::string docId;
    float score;
};

class SearchCache {
public:
    // 添加一条结果到缓存尾部（保持插入顺序）
    void add(const ResultPage& page) {
        pages_.emplace_back(page);
    }

    // 移除低于阈值的结果（严格小于 threshold）
    // 实现：erase-remove 惯用法
    //  - std::remove_if 将不满足移除条件的元素“稳定地”搬移到前部，返回新的逻辑末端迭代器
    //  - vector::erase 物理擦除 [newEnd, end()) 区间，真正缩短容器大小
    // 复杂度：O(n)
    void removeLowScore(float threshold) {
        auto newEnd = std::remove_if(
            pages_.begin(), pages_.end(),
            [threshold](const ResultPage& page) {
                return page.score < threshold; // 严格小于则移除
            }
        );
        pages_.erase(newEnd, pages_.end());
    }

    // 分页获取子区间（返回副本）
    // 参数：
    //   offset —— 起始偏移（假定 offset >= 0）
    //   limit  —— 限制返回数量（假定 limit >= 0）
    // 返回：拷贝的子 vector。若 offset 超过范围或 limit 为 0，则返回空。
    // 复杂度：O(k)（k 为返回元素个数）
    // 注意：
    //   - 该实现未做负值校验；传入负值会导致未定义行为（迭代器越界）。
    //   - 若希望零拷贝，可改为返回迭代器区间或 std::span<const ResultPage>（C++20）。
    std::vector<ResultPage> page(int offset, int limit) const {
        const int end = std::min(offset + limit, static_cast<int>(pages_.size()));
        if (offset >= end) return {};
        return std::vector<ResultPage>(pages_.begin() + offset, pages_.begin() + end);
    }

private:
    // 结果容器：按插入顺序存放
    std::vector<ResultPage> pages_;
};

int main() {
    SearchCache cache;

    // 添加若干条结果（示例数据）
    cache.add({"docA", 0.95f});
    cache.add({"docB", 0.42f});
    cache.add({"docC", 0.87f});

    // 移除分数低于 0.5 的结果（此处会移除 docB）
    cache.removeLowScore(0.5f);

    // 获取从 offset=0 开始，最多 10 条的分页结果（返回副本）
    auto page = cache.page(0, 10);

    std::cout << "Remaining results: " << page.size() << '\n';
    for (const auto& result : page) {
        std::cout << result.docId << " score=" << result.score << '\n';
    }

    // 提示：
    // - 若需按分数降序分页，可在 add 时插入到合适位置（保持有序），或在分页前调用稳定排序：
    //   std::stable_sort(pages_.begin(), pages_.end(),
    //                    [](auto& a, auto& b){ return a.score > b.score; });
    // - 为减少拷贝，可将 page 改为输出迭代器区间，或返回指向内部数据的视图对象（注意生命周期）。
    return 0;
}